// any 类型表示没有任何限制，该类型的变量可以赋予任意类型的值。
let x: any

x = 123
x = '123'
x = true

// 使用any声明 和写js将无区别 也失去了ts编写代码的意义 any是顶层类型 top type
let foo: any = 'Hello'
foo(1)
foo.bar = 100

function add(x, y) {
  return x + y
}

add(1, '123')
add(1, [2, 3, 4])

// const bar   const声明的类型必须初始化

// 环境污染
let x1: any = 'Hello'
let y1: number
y1 = x1 // 赋值成功了~
y1 * 123
y1.toFixed(2)
// 污染其他具有正确类型的变量，把错误留到运行时，这就是不宜使用any类型的另一个主要原因。
// 任何类型可以赋值给any   any也可以赋值给任意具体类型

// 引入 unknow 来规避污染问题
let var01: unknown = 123
// let var02: boolean = var01
// let var03: number = var01
let var04: unknown = var01
let var05: any = var01

// 不能直接调用unknown类型变量的方法和属性。
let var06: unknown = { foo: 123 }
// var06.foo  报错

// 经过类型缩小 unknown类型的变量才能使用
let var07: unknown = 1
if (typeof var07 === 'number') {
  var07 += 1
}

let var08: unknown = '123'
if (typeof var08 === 'string') {
  console.log(var08.length)
}

// unkonwn 可以看作是更安全的any  它同样是 top type 但是规避了变量污染问题


// never类型 空集
let a: never
// a = 123
// a = '123'

// never 可以赋值给任意特定类型 空集  bottom type
function f(): never {
  throw new Error('123')
}

let b: number = f()
let c: string = f()